<?php

vendor('xhtml');
vendor('expr/type');

class EditFormHelper extends AppHelper
{
	public $helpers = array('EHtml', 'Html', 'Form', 'Javascript');
	public $formName = '';
	public $setOpen = false;
	public $groupOpen = false;
	public $defaultAllowInput = true;
	public $allowInput = true;
	public $readonlyFields = array();
	public $showedFields = null;
	public $unshowedFields = null;
	public $afterCntent = '';
	public $render = true;
	public $nnn = null;

	public $DOM = null;

	function __construct()
	{
		$args =& func_get_args();call_user_func_array(array('parent', __FUNCTION__), $args);

	    static $formName = '';
	    static $setOpen = false;
	    static $groupOpen = false;
	    static $defaultAllowInput = true;
	    static $allowInput = true;
	    static $readonlyFields = array();
	    static $showedFields = null;
	    static $unshowedFields = null;
	    static $afterCntent = '';
	    static $render = true;
	    static $nnn = null;
	    static $DOM = null;

	    $this->formName =& $formName;
	    $this->setOpen =& $setOpen;
	    $this->groupOpen =& $groupOpen;
	    $this->defaultAllowInput =& $defaultAllowInput;
	    $this->allowInput =& $allowInput;
	    $this->readonlyFields =& $readonlyFields;
	    $this->showedFields =& $showedFields;
	    $this->unshowedFields =& $unshowedFields;
	    $this->afterCntent =& $afterCntent;
	    $this->render =& $render;
	    $this->nnn =& $nnn;
        $this->DOM = null;
    }

    public function beforeRender()
    {
        $this->data =& $this->Form->data;
    }

	protected function resetParameters()
	{
	    $this->formName = '';
	    $this->setOpen = false;
	    $this->groupOpen = false;
	    $this->defaultAllowInput = true;
	    $this->allowInput = true;
	    $this->readonlyFields = array();
	    $this->showedFields = null;
	    $this->unshowedFields = null;
	    $this->afterCntent = '';
	    $this->render = true;
	    $this->nnn = null;
        $this->DOM = null;
	}

	function getFormId()
	{
        return strtolower($this->formName);
	}

	function create($name, $parameters=array())
	{
	    if (isset($parameters['url'])) {
    	    $parameters['action'] = $parameters['url'];
    	    $parameters['url'] = 1;
	    }

	    $this->resetParameters();
	    $this->formName = $name;
	    $result = '';

	    $this->nnn = $this;

	    if (isset($parameters['defaultAllowInput'])) {
	        $this->defaultAllowInput = $parameters['defaultAllowInput'];
	        unset($parameters['defaultAllowInput']);
	    }

	    if (isset($parameters['allowInput'])) {
	        $this->allowInput = $parameters['allowInput'];
	        unset($parameters['allowInput']);
	    }

	    if (isset($parameters['readonlyFields'])) {
	        $this->readonlyFields = $parameters['readonlyFields'];
	        unset($parameters['readonlyFields']);
	    }

	    if (isset($parameters['showedFields'])) {
	        $this->showedFields = $parameters['showedFields'];
	        unset($parameters['showedFields']);
	    }

	    if (isset($parameters['unshowedFields'])) {
	        $this->unshowedFields = $parameters['unshowedFields'];
	        unset($parameters['unshowedFields']);
	    }

	    $result .= $this->Form->create($name, $parameters);
        $result .= $this->_header($parameters);

	    return $result;
	}

	function header($caption, $parameters=array())
	{
	    $result = '';
	    $result .= '<h5 class="no-margins no-color">';
        if (empty($parameters['unescape'])) {
            $result .= htmlspecialchars($caption, ENT_NOQUOTES, DEFAULT_CHARSET);
        } else {
            $result .= $caption;
        }
	    $result .= '</h5>';
	    if (!empty($parameters['description'])) {
            $result .= '<em>';
            if (empty($parameters['unescape'])) {
                $result .= htmlspecialchars($parameters['description'], ENT_NOQUOTES, DEFAULT_CHARSET);
            } else {
                $result .= $parameters['description'];
            }
            $result .= '</em>';
	    }
	    return $this->cell($result);
	}

	function chackByDependent(&$parameters)
	{
	    $cond = true;

        if (!empty($parameters['dependent'])) {
            if (empty($parameters['id'])) {
                $parameters['id'] = '';
            }
            $id =& $parameters['id'];

            if (is_object($parameters['dependent']) && is_a($parameters['dependent'], 'Expression')) {
            } else {
                $dependent = strval($parameters['dependent']);

                $leadingFields = array();
                preg_match_all('/`([^`]+)`/s', $dependent, $matches, PREG_PATTERN_ORDER);
                if (isset($matches[1]) && count($matches[1])) {
                    for ($i = 0; $i < count($matches[1]); $i++) {
                        $leadingFields[] = $matches[1][$i];
                    }
                }

                if ($leadingFields) {

                    $knownLeadingFields = array();
                    $unknownLeadingFields = array();
                    $patterns = array();
                    $replaces = array();

                    $formId = $this->getFormId();
                    $jsCond  = '';
                    foreach ($leadingFields as $fieldName) {
                        $patterns[] = "/(`{$fieldName}`)/s";
                        if (! $this->allowInput || in_array($fieldName, $this->readonlyFields)) {
                            $knownLeadingFields[] = $fieldName;
                            $replaces[] = "'".addslashes($this->data[$this->formName][$fieldName])."'";
                        } else {
                            $formItemName = "data[{$this->formName}][{$fieldName}]";
                            $replaces[] = '$("#'.$formId.'").get()[0].elements["'.$formItemName.'"].value';
                        }
                    }

                    $expression = preg_replace($patterns, $replaces, $dependent);

                    if (count($unknownLeadingFields = array_diff($leadingFields, $knownLeadingFields))) {
                        if (empty($id)) {
                            $id = Page::objForView()->genId();
                        }
                        $endl = Configure::read('debug') ? "\n" : "";

                        $showComans = '$("#'.$id.'").fadeIn("slow");';
                        $hideComans = '$("#'.$id.'").hide();';
                        $generatedId = Page::objForView()->genId();
                        $funcName = $generatedId.'_ToggleForForm';
                        $onchange = "{$funcName}();";

                        $setOnchange = '';
                        foreach ($unknownLeadingFields as $fieldName) {
                            $generatedId = Page::objForView()->genId();
                            $formItemName = "data[{$this->formName}][{$fieldName}]";

                            $setOnchange .= 'var '.$generatedId.'_form = $("#'.$formId.'").get()[0];'.$endl;
                            $setOnchange .= 'var '.$generatedId.'_element = $('.$generatedId.'_form.elements["'.$formItemName.'"]);'.$endl;
                            $setOnchange .= $generatedId.'_element.change('.$funcName.').change();'.$endl;
                        }
                        $function = 'function '.$funcName.'() '.$endl.'{'.$endl.'if ('.$expression.') {'.$endl.''.$showComans.''.$endl.'} else {'.$endl.''.$hideComans.''.$endl.'};'.$endl.'}';
                        $this->afterCntent .= $this->Javascript->codeBlock($endl.$setOnchange.$function.$endl.$onchange.$endl);
                    } else {
                        try {
                            @eval('$cond = ('.$expression.');');
                        } catch (Exception $e) {}
                    }
                } else {
                    $expression =& $dependent;
                    try {
                        @eval('$cond = ('.$expression.');');
                    } catch (Exception $e) {}
                }

                unset($parameters['dependent']);
            }
        }

        return $cond;
	}

	function startGroup($id = null, $parameters=array())
	{
	    $result = '';
	    if ($this->groupOpen) {
	        $result .= $this->endGroup();
	    }

	    $parameters['id'] = $id;
	    if (! $this->chackByDependent($parameters)) {
	        $this->render = false;
	    }
	    if (! $this->render) {
	        return '';
	    }

        $this->groupOpen = true;

        $idAttr = '';
        if (!empty($parameters['id'])) {
            $idAttr = ' id="'.$parameters['id'].'"';
        }
        $result .= '<tbody'.$idAttr.'>';

	    return $result;
	}

	function endGroup()
	{
	    $result = '';
	    if ($this->groupOpen) {
            $result .= '</tbody>';
	    }

	    $this->render = true;
	    $this->groupOpen = false;
	    return $result;
	}

	function startSet($caption = null, $parameters=array())
	{
	    $result = '';
	    if ($this->setOpen) {
	        $result .= $this->endSet();
	    }
        $result .= $this->cell('<span></span>');
        $this->setOpen = true;
	    $content = '';
	    if (!empty($caption)) {
            $content .= '<h2 class="no-margins no-color">'.$caption.'</h2>';
            if (!empty($parameters['description'])) {
                $content .= '<em>'.$parameters['description'].'</em>';
            }
	    /*} else {
            $content .= '<span></span>';*/
	    }

	    if (strlen($content)) {
            $result .= $this->cell($content);
	    }

	    return $result;
	}

	function endSet()
	{
	    $result = '';
	    if ($this->setOpen) {
    	    $result = $this->cell('<span></span>');
            $this->setOpen = false;
    	    /*$result .= $this->cell('<span></span>');*/
	    }

	    return $result;
	}

	function mayShow($fieldName, $parameters=array())
	{
	    if (isset($this->unshowedFields) && in_array($fieldName, $this->unshowedFields)) {
	        return false;
	    }
	    if (isset($this->showedFields) && in_array($fieldName, $this->showedFields)) {
	        return true;
	    }

        return true;
	}

	function datetimeView($caption, $value, $parameters=array())
	{
	    vendor('date');

		return $this->textView($caption, Date::Full(Date::SQL2UNIX($value)));
	}

	function dateView($caption, $value, $parameters=array())
	{
	    vendor('date');

		return $this->textView($caption, Date::Full(Date::SQL2UNIX($value), $parameters));
	}

	function initCalendar()
	{
	    static $alreadyExistsCalendar = false;
		$lang = Configure::read('Config.language');
		if(empty($lang))
			$lang = 'en';
	    if (!$alreadyExistsCalendar) {
    		Page::addCSS('../js/jscalendar/calendar-win2k-1');
    		Page::addJS('jscalendar/calendar');
    		Page::addJS('jscalendar/lang/calendar-'.$lang);
    		Page::addJS('jscalendar/calendar-setup');

            $alreadyExistsCalendar = true;
		}
	}

	function calendar($fieldName, $showTime = false, $options = array(), $readOnly = false, $fromDateId = null, $toDateId = null)
	{
	    $formName = $this->formName;
	    $this->initCalendar();

	    $showSeconds = isset($options['showSeconds']) ? (bool)$options['showSeconds'] : false;

		if ($readOnly) {
			$options = array_merge($options, array('readonly' => 'true'));
		}

		$input_options = array('type' => 'text', 'error'=>false);
		if (!$showTime) {
		    if (!empty($this->data[$formName][$fieldName])) {
                $input_options['value'] = date('Y-m-d', strtotime($this->data[$formName][$fieldName]));
		    }
		    $input_options['size'] = '10';
		}
		$input = $this->Form->input($fieldName, array_merge($options, $input_options));

		$r = ' id="[a-zA-Z_0-9]+"';
		ereg($r, $input, $regs);
		ereg('"[a-zA-Z_0-9]+"',$regs[0],$regs);
		$id = substr($regs[0], 1, strlen($regs[0]) - 2);

		$button = $this->EHtml->iconButton("calendar", array("id" => $id."Trigger", "button" => true));
		$cal = array('id' => $id, 'showTime' => $showTime);
		if ($fromDateId) {
			$cal['fromDateId'] = $fromDateId;
		}
		if ($toDateId) {
			$cal['toDateId'] = $toDateId;
		}

		$input = '<span class="nw"><span' . substr($input, strlen('<div'));
		$input = substr($input, 0, strlen($input) - strlen('</div>')) . $button . '</span></span>';
		return $input.$this->setupCalendar($cal);
	}

	function setupCalendar($item)
	{
		return $this->Javascript->codeBlock("Calendar.setup({"
            ."inputField: '{$item['id']}', "
            .(($item['showTime']) ? "showsTime: true, timeFormat: '24', ifFormat: '%Y-%m-%d %H:%M', " : "ifFormat: '%Y-%m-%d', ")
            ."button: '{$item['id']}Trigger'"
		."});");
	}

	function datetime($fieldName, $caption, $parameters=array())
	{
	    if ($this->getAllowInput($fieldName, $parameters)) {
            return $this->field($fieldName, $caption,
                $this->calendar($fieldName, true, array('label' => ''), true)
            );
	    } else {
    	    if (! $this->mayShow($fieldName, $parameters)) {
    	        return '';
    	    }
            return $this->datetimeView($caption, $this->data[$this->formName][$fieldName], $parameters=array());
	    }
	}

	function date($fieldName, $caption, $parameters=array())
	{
	    if ($this->getAllowInput($fieldName, $parameters)) {
            return $this->field($fieldName, $caption,
                $this->calendar($fieldName, false, am(array('label' => ''), $parameters), true)
            );
	    } else {
    	    if (! $this->mayShow($fieldName, $parameters)) {
    	        return '';
    	    }
            return $this->dateView($caption, $this->data[$this->formName][$fieldName], $parameters=array());
	    }
	}

	function textView($caption, $value, $parameters=array())
	{
	    $result = '';

	    $coma = !array_key_exists('coma', $parameters) || !empty($parameters['coma']);

	    $vertical = !empty($parameters['vertical']);
	    $horizontal = empty($parameters['vertical']) || !empty($parameters['horizontal']);

	    if (!is_null($caption)) {
    		$result .= $this->Form->label(null, $caption);
    		if ($coma) {
                $result .= ':';
    		}
    		if ($horizontal) {
                $result .= ' ';
    		}
	    }
	    if (1||!is_null($value)) {
	        $add_class = (is_null($caption) || $vertical) ? ' neg-margin-l' : '';
	        if ($vertical) {
                $result .= '<table cellpadding="0" class="sys_layout form-item-view'.$add_class.'"><tr class="sys_clear"><td class="padding-b sys_clear">';
	        } else {
                $result .= '<span class="form-item-view'.$add_class.'">';
	        }
            if (empty($parameters['unescape'])) {
                $result .= htmlspecialchars($value, ENT_NOQUOTES, DEFAULT_CHARSET);
            } else {
                $result .= $value;
            }
	        if ($vertical) {
                $result .= '</td></tr></table>';
	        } else {
                $result .= '</span>';
	        }
	    } else {
	        $result .= '—';
	    }
        if (!empty($parameters['description'])) {
            $result .= '<div class="field-description">'.$parameters['description'].'</div>';
        }

		return $this->cell($result, $parameters);
	}

	function insertCell($content, $parameters=array())
	{
	    if (! $this->render) {
	        return '';
	    }
	    $result = '';
		$result .= $this->_cellContainerBegn();
		$result .= $content;
		$result .= $this->_cellContainerEnd();

		return $result;
	}

	function text($fieldName, $caption, $parameters=array())
	{
	    if ($this->getAllowInput($fieldName, $parameters)) {
    	    if (!empty($parameters['vertical']) && empty($parameters['size'])) {
    	       $parameters['size'] = 53;
    	    }
    	    return $this->field(
    	       $fieldName,
    	       $caption,
    	       $this->Form->text($fieldName, $parameters),
    	       $parameters);
	    } else {
	        $controls = array(array(
	           'fieldName' => $fieldName,
	           'content' => $this->textControlView($this->data[$this->formName][$fieldName], $parameters),
	        ));
	        return $this->element($caption, $controls, $parameters);
	    }
	}

	/**
	 * Поле для ввода денежной суммы
	 *
	 * @param string $fieldName
	 * @param string $caption
	 * @param array $currencies
	 * @param array $parameters
	 * @return string
	 */
	function amount($fieldName, $caption, $currencies, $parameters=array())
	{
	    if (! $this->getAllowInput($fieldName, $parameters)) {
	        $parameters['allowInputValue'] = false;
	        $parameters['allowInputCurrency'] = false;
	    }
	    $valueField = 'amount';
	    $currencyField = 'currency';
	    if (is_array($fieldName)) {
            $valueField = @$fieldName[0];
            $currencyField = @$fieldName[1];
	    } else {
	        $valueField = $fieldName;
	    }
	    if (! $this->mayShow($valueField, $parameters) && ! $this->mayShow($currencyField, $parameters)) {
	        return '';
	    }

        $error = $this->error($valueField);
        if (!strlen($error)) {
            $error = $this->error($currencyField);
        }
        if (strlen($error)) {
            $parameters['error'] = $error;
        }
        $showEmpty = false;
        if (isset($parameters['showEmpty'])) {
            $showEmpty = $parameters['showEmpty'];
            unset($parameters['showEmpty']);
        }
        $allows = array('value' => $this->getAllowInput($valueField), 'currency' => $this->getAllowInput($currencyField));
        if (isset($parameters['allowInputValue'])) {
            $allows['value'] = $parameters['allowInputValue'];
            unset($parameters['allowInputValue']);
        }
        if (isset($parameters['allowInputCurrency'])) {
            $allows['currency'] = $parameters['allowInputCurrency'];
            unset($parameters['allowInputCurrency']);
        }

        if (empty($allows['value']) && empty($allows['currency'])) {
            $parameters['unescape'] = true;
            return $this->textView($caption, $this->drawAmount($this->data[$this->formName][$valueField], $this->data[$this->formName][$currencyField]), $parameters);
        } else {
            $valueInput = '';
            $currencyInput = '';
            if (empty($allows['value'])) {
                $valueInput = '<span class="form-item-view">'
                    .$this->drawAmount($this->data[$this->formName][$valueField])
                    .'</span>';
            } else {
                $valueInput = $this->Form->text($valueField, array('size' => 7));
            }
            if (empty($allows['currency'])) {
                $currencyInput = $this->drawCurrency($this->data[$this->formName][$currencyField]);
            } else {
                $currencyInput = $this->Form->select($currencyField, $currencies, null, array(), $showEmpty);
            }
            $content = $valueInput.' '.$currencyInput;
            return $this->field($valueField, $caption, $content, $parameters);
        }
	}

	function drawAmount($amount, $currency='')
	{
	    $amount = empty($amount) ? '0.0' : $amount;
        return '<span class="amount">'
            .$this->num_fo($amount).'&nbsp;'
            .$this->drawCurrency($currency)
            .'</span>';
	}

	function drawAmountTXT($amount, $currency='')
	{
	    $amount = empty($amount) ? '0.0' : $amount;
        return $this->num_foTXT($amount).' '
            .$this->drawCurrencyTXT($currency);
	}

    function num_fo($number, $dec_sep='.')
    {
        $number = str($number)->toString();
        $with_minus = false;
        if (str($number)->length) {
            if (str($number)->toChar(0) == '-') {
                $number = str($number)->substr(1);
                $number = $number->toString();
                $with_minus = true;
            }
        }
        $p_dec_separator = ',';
        $array_amount = explode($dec_sep, $number);
        $int_part = $array_amount[0];
        $dec_part = empty($array_amount[1]) ? '00' : $array_amount[1];
        $tmp_sep = ' ';
        $int_groups_array = explode($tmp_sep, substr(strrev(chunk_split(strrev($int_part), 3, ' ')), strlen($tmp_sep)));
        $out = '';
        $out .= '<span class="int-part">';
        if ($with_minus) {
            $out .= '−';
        }
        $out .= $int_groups_array[0];
        for ($i = 1; $i < count($int_groups_array); $i++) {
            $out .= '<span class="group">'.$int_groups_array[$i].'</span>';
        }
        $out .= $p_dec_separator;
        $out .= '</span>';
        //$out .= intval($dec_part)===0 ? '–' : $dec_part;
        $out .= $dec_part;

        return $out;
    }

    function num_foTXT($number, $dec_sep='.')
    {
        $number = str($number)->toString();
        $with_minus = false;
        if (str($number)->length) {
            if (str($number)->toChar(0) == '-') {
                $number = str($number)->substr(1);
                $number = $number->toString();
                $with_minus = true;
            }
        }
        $p_dec_separator = ',';
        $array_amount = explode($dec_sep, $number);
        $int_part = $array_amount[0];
        $dec_part = empty($array_amount[1]) ? '00' : $array_amount[1];
        $tmp_sep = ' ';
        $int_groups_array = explode($tmp_sep, substr(strrev(chunk_split(strrev($int_part), 3, ' ')), strlen($tmp_sep)));
        $out = '';
        if ($with_minus) {
            $out .= '−';
        }
        $out .= $int_groups_array[0];
        for ($i = 1; $i < count($int_groups_array); $i++) {
            $out .= ' '.$int_groups_array[$i];
        }
        $out .= $p_dec_separator;
        $out .= '';
        //$out .= intval($dec_part)===0 ? '–' : $dec_part;
        $out .= $dec_part;

        return $out;
    }

	function drawCurrency($currency)
	{
        $suf = '';
        switch ($currency) {
        case 'EUR':
            $suf = '€';
            break;

        case 'USD':
            $suf = '$';
            break;

        case 'EP':
            $suf = __d(null, 'eCurrency', true);
            break;

        default:
            //throw new Exception();
        }

        return strlen($suf) ? '<span class="curr">'.$suf.'</span>' : '';
	}

	function drawCurrencyTXT($currency)
	{
        $suf = '';
        switch ($currency) {
        case 'EUR':
            $suf = '€';
            break;

        case 'USD':
            $suf = '$';
            break;

        case 'EP':
            $suf = __d(null, 'eCurrency', true);
            break;

        default:
            //throw new Exception();
        }

        return strlen($suf) ? $suf : '';
	}

	function getAllowInput($fieldName, $parameters=array())
	{
	    $allow = true;
	    if ($this->allowInput) {
	        if (in_array($fieldName, $this->readonlyFields)) {
	            $allow = false;
	        } else {
        	    if (isset($parameters['allowInput'])) {
        	        $allow = $parameters['allowInput'];
        	    } else {
                    $allow = $this->defaultAllowInput;
        	    }
	        }
	    } else {
	        $allow = false;
	    }
	    if (! $allow && !in_array($fieldName, $this->readonlyFields)) {
	        $this->readonlyFields[] = $fieldName;
	    }

	    return $allow;
	}

	function textarea($fieldName, $caption, $parameters=array())
	{
	    if ($this->getAllowInput($fieldName, $parameters)) {
    	    if (!empty($parameters['horizontal'])) {
    	        $parameters['horizontal'] = true;
    	        $parameters['vertical'] = false;
    	    } else {
    	        $parameters['horizontal'] = false;
    	        $parameters['vertical'] = true;
    	    }
    	    if (!empty($parameters['vertical']) && empty($parameters['cols'])) {
    	       $parameters['cols'] = 40;
    	    }
    	    if (empty($parameters['rows'])) {
    	       $parameters['rows'] = 5;
    	    }

    	    return $this->field(
    	       $fieldName,
    	       $caption,
    	       $this->Form->textarea($fieldName, $parameters),
    	       $parameters);
	    } else {
	        $controls = array(array(
	           'fieldName' => $fieldName,
	           'content' => $this->textareaControlView($this->data[$this->formName][$fieldName], $parameters),
	        ));
	        return $this->element($caption, $controls, $parameters);
	    }
	}

	function secureAnswer($operation_num)
	{
        return $this->text('secure_answer', __d(null, 'secure_answer_input', true), array('vertical' => true, 'description' => __d(null, 'operation_number', true).': '.$operation_num));?><?php
	}

	function select($fieldName, $caption, $options = array(), $selected = null, $attributes = array(), $showEmpty = '')
	{
	    $parameters = $attributes;

	    if ($this->getAllowInput($fieldName, $parameters)) {
    	    return $this->field(
    	       $fieldName,
    	       $caption,
    	       $this->Form->select($fieldName, $options, $selected, $attributes, $showEmpty),
    	       $parameters);
	    } else {
	        $value = empty($this->data[$this->formName][$fieldName]) ? '' : $options[$this->data[$this->formName][$fieldName]];
	        $controls = array(array(
	           'fieldName' => $fieldName,
	           'content' => $this->textControlView($value, $parameters),
	        ));
	        return $this->element($caption, $controls, $parameters);
	    }
	}

	function field($fieldName, $caption, $content, $parameters=array())
	{
	    if (! $this->mayShow($fieldName, $parameters)) {
	        return '';
	    }
	    $result = '';

	    $coma = !array_key_exists('coma', $parameters) || !empty($parameters['coma']);

	    $vertical = !empty($parameters['vertical']);
	    $horizontal = empty($parameters['vertical']) || !empty($parameters['horizontal']);

        $error = !empty($parameters['error']) ? $parameters['error'] : $this->error($fieldName);

        $class = '';

        $class .= strlen($error) ? (strlen($class) ? " " : "") . "errored" : "";

        $class = strlen($class) ? ' class="'.$fieldName.'"' : "";

        $result .= '<div'.$class.'>';

	    if (!is_null($caption)) {
    		$result .= $this->Form->label($fieldName, $caption);
    		if ($coma) {
                $result .= ':';
    		}
    		if ($horizontal) {
                $result .= ' ';
    		}
    		if ($vertical) {
                $result .= '<br />';
    		}
	    }

        if (!empty($parameters['description'])) {
            $result .= '<div class="field-description">'.$parameters['description'].'</div>';
        }
		if (!empty($error)) {
            $result .= '<div class="field-error">'.$error.'</div>';
        } elseif (!empty($parameters['comment'])) {
            $result .= '<div class="field-comment">'.$parameters['comment'].'</div>';
        }

	    if (!empty($parameters['escape'])) {
	        unset($parameters['escape']);
	        $content = htmlentities($content);
	    }
		$result .= $content;

        $result .= '</div>';

        return $this->cell($result, $parameters);
	}

	function selectControl($fieldName, $options = array(), $selected = null, $parameters = array(), $showEmpty = '')
	{
	    if ($this->getAllowInput($fieldName, $parameters)) {
            return $this->Form->select($fieldName, $options, $selected, $parameters, $showEmpty);
	    } else {
	        $value = empty($this->data[$this->formName][$fieldName]) ? '' : $options[$this->data[$this->formName][$fieldName]];
	        return $this->textControlView($value, $parameters);
	    }
	}

	function textControlView($value, $parameters=array())
	{
	    $vertical = false;
	    if (isset($parameters['vertical'])) {
	        $vertical = (bool)$parameters['vertical'];
	    }

        $escape = true;
        if (isset($parameters['unescape'])) {
            $escape = !(bool)$parameters['unescape'];
        } elseif (isset($parameters['escape'])) {
            $escape = !(bool)$parameters['unescape'];
        }
        $content = null;
        if ($escape) {
            $value = htmlspecialchars($value, ENT_NOQUOTES, DEFAULT_CHARSET);
        }
        $content = XHTMLRaw($value);

	    $container = XHTMLElement('span',
            $content
        );

        $container->addClass('form-item-view');

		return $container->render();
	}

	function textareaControlView($value, $parameters=array())
	{
	    $vertical = false;
	    if (isset($parameters['vertical'])) {
	        $vertical = (bool)$parameters['vertical'];
	    }

        $escape = true;
        if (isset($parameters['unescape'])) {
            $escape = !(bool)$parameters['unescape'];
        } elseif (isset($parameters['escape'])) {
            $escape = !(bool)$parameters['unescape'];
        }
        $content = null;
        if ($escape) {
            $value = htmlspecialchars($value, ENT_NOQUOTES, DEFAULT_CHARSET);
        }
        $content = XHTMLRaw(nl2br($value));

	    $container = XHTMLElement('table',
            XHTMLElement('tr', XHTMLAttribute('class', 'sys_clear'),
                XHTMLElement('td', XHTMLAttribute('class', 'padding-b sys_clear'),
                    $content
                )
            )
        );

        $container->addClass('sys_layout');
        $container->addClass('form-item-view');

		return $container->render();
	}

	function textControl($fieldName, $parameters=array())
	{
	    if ($this->getAllowInput($fieldName, $parameters)) {
            return $this->Form->text($fieldName, $parameters);
	    } else {
	        return $this->textControlView(@$this->data[$this->formName][$fieldName], $parameters);
	    }
	}

	function textareaControl($fieldName, $parameters=array())
	{
	    if ($this->getAllowInput($fieldName, $parameters)) {
            return $this->Form->textarea($fieldName, $parameters);
	    } else {
	        return $this->textareaControlView(@$this->data[$this->formName][$fieldName], $parameters);
	    }
	}

	function element($caption, $controls=array(), $parameters=array())
	{
        $container = XHTMLElement('div');

	    $vertical = false;
	    if (isset($parameters['vertical'])) {
	        $vertical = (bool)$parameters['vertical'];
	    }
	    $coma = true;
	    if (isset($parameters['coma'])) {
	        $coma = (bool)$parameters['coma'];
	    }
	    $required = false;
	    if (isset($parameters['required'])) {
	        $required = (bool)$parameters['required'];
	    }
	    if ($required) {
            $container->addClass("required");
	    }
        $labelFor = @$controls[0]['fieldName'];
        if (isset($parameters['mainField'])) {
            $labelFor = $parameters['mainField'];
        }

        $error = '';
        if (isset($parameters['error'])) {
            $error = $parameters['error'];
        } else {
    	    foreach ($controls as $control) {
    	        if (!empty($control['error'])) {
    	            $error = $control['error'];
    	            break;
    	        } elseif (strlen($this->error($control['fieldName']))) {
    	            $error = $this->error($control['fieldName']);
    	            break;
    	        }
    	    }
        }
        if (!empty($error)) {
            $container->addClass("errored");
        }

	    $empty = true;
	    $readonly = true;
	    $show = true;
	    foreach ($controls as $control) {
	        $readonly  &= ! $this->getAllowInput($control['fieldName']);
	        $empty     &= empty($this->data[$this->formName][$control['fieldName']]);
	        $show      &= $this->mayShow($control['fieldName']);
	    }
	    if (!$show || ($readonly && !$required && $empty)) {
	        return '';
	    }

	    if (!is_null($caption)) {

            $attrs = array();
            if (!empty($labelFor)) {
                $attrs['for'] = $labelFor;
            }

            $caption = trim($caption);
            if ($coma) {
                mb_regex_encoding(DEFAULT_CHARSET);
                $caption = mb_ereg_replace(":+$", "", $caption);
                $caption .= ':';
            }
            $container->appendChild(XHTMLElement('label', XHTMLAttributes($attrs),
                XHTMLText($caption)
            ));

    		if (!$vertical) {
                $container->appendChild(XHTMLText(' '));
    		}
	    }

	    $otherElements = array();
        if (!empty($parameters['description'])) {
            $otherElements[] = XHTMLElement('div', XHTMLAttribute('class', 'field-description'),
                XHTMLText($parameters['description'])
            );
        }
		if (!empty($error)) {
            $otherElements[] = XHTMLElement('div', XHTMLAttribute('class', 'field-error'),
                XHTMLRaw($error)
            );
        } elseif (!empty($parameters['comment'])) {
            $otherElements[] = XHTMLElement('div', XHTMLAttribute('class', 'field-comment'),
                XHTMLText($parameters['comment'])
            );
        }

        if ($vertical) {
            $content =& XHTMLElement('div');
            foreach ($controls as $control) {
        	    if (! $this->mayShow($control['fieldName'])) {
        	        continue;
        	    }
                $tmp_content = null;
                if (is_object($control['content']) && is_a($control['content'], 'XMLNode')) {
                    $tmp_content =& $control['content'];
                } else {
                    $tmp_content = XHTMLRaw(TypeString::convert($control['content']));
                }
                $content->appendChild($tmp_content);
            }
            if (!$this->getAllowInput(@$controls[0]['fieldName'])) {
                $content->addClass('neg-margin-l');
            }
            $otherElements[] = $content;
        } else {
            foreach ($controls as $control) {
                $tmp_content = null;
                if (is_object($control['content']) && is_a($control['content'], 'XMLNode')) {
                    $tmp_content =& $control['content'];
                } else {
                    $tmp_content = XHTMLRaw(TypeString::convert($control['content']));
                }
                $container->appendChild($tmp_content);
            }
        }
        foreach ($otherElements as $element) {
            $container->appendChild($element);
        }

        $parameters['error'] = $error;
        $parameters['required'] = $required;
        $parameters['readonly'] = $readonly;
	    unset($parameters['vertical'], $parameters['horizontal'], $parameters['coma'], $parameters['comment'], $parameters['description'], $parameters['mainField']);
        return $this->cell($container->render(), $parameters);
	}

	function cell($content, $parameters=array())
	{
	    if (! $this->render) {
	        return '';
	    }
	    $parameters['__id'] = @$parameters['id'];

	    if (! $this->chackByDependent($parameters)) {
	        return '';
	    }

	    $parameters['idContainer'] = @$parameters['id'];
	    $parameters['id'] = $parameters['__id'];

	    $result = '';

		$result .= $this->_cellHeader($parameters);
		$result .= $content;
		$result .= $this->_cellFooter($parameters);

		return $result;
	}

	function _cellContainerBegn($parameters=array())
	{
	    $id = !empty($parameters['idContainer']) ? ' id="'.$parameters['idContainer'].'"' : '';
	    ob_start();
    	    if (!$this->groupOpen) {
                ?><tbody><?php
    	    }
            ?><tr <?=$id;?><?=($this->setOpen ? 'class="hightlight sys_clear"' : 'class="sys_clear"');?>><?php
            ?><td class="form-element-container sys_clear"><?php
        return ob_get_clean();
	}

	function _cellHeader($parameters=array())
	{
	    $add_class = !empty($parameters['class']) ? $parameters['class'] : '';
	    $add_class .= strlen($add_class) ? ' ' : '';
        return $this->_cellContainerBegn($parameters).'<div class="'.$add_class.'form-element">';
	}

	function _cellFooter($parameters=array())
	{
        return '</div>'.$this->_cellContainerEnd($parameters);
	}

	function _cellContainerEnd($parameters=array())
	{
	    ob_start();
            ?></td><?php
            ?></tr><?php
    	    if (!$this->groupOpen) {
                ?></tbody><?php
    	    }
        return ob_get_clean();
	}

	function end($parameters=array())
	{
        $result = '';

        if ($this->groupOpen) {
            $result .= $this->endGroup();
        }
        if ($this->setOpen) {
            $result .= $this->endSet();
        }
        $result .= $this->_footer($parameters);
        $result .= $this->Form->end();
        $result .= $this->afterCntent;

	    $this->resetParameters();
	    return $result;
	}

	protected function _header($parameters=array())
	{
	    ob_start();

	    $classCSS = 'form-elements sys_clear';
	    if (isset($parameters['formStyle']) && $parameters['formStyle'] == 'inner') {
            $classCSS .= strlen($classCSS) ? ' ' : '';
            $classCSS .= 'form-inner';
	    }
	    $classCSS = strlen($classCSS) ? 'class="'.$classCSS.'" ' : '';
        ?><table <?=$classCSS;?>cellpadding="0"><?php

        return ob_get_clean();
	}

	protected function _footer($parameters=array())
	{
	    ob_start();

        ?></table><?php

        return ob_get_clean();
	}

	function submit($caption = null, $parameters = array())
	{
	    $parameters['div'] = false;
	    return $this->Form->submit($caption, $parameters);
	}

	function button($fieldName, $caption, $parameters = array())
	{
	    $parameters['name'] = "data[{$this->formName}][{$fieldName}]";
		return $this->buttonTag($caption, $parameters);
	}

	function submitTag($caption, $parameters = array())
	{
	    $parameters['type'] = 'submit';
		return $this->_buttonTag($caption, $parameters);
	}

	function buttonTag($caption, $parameters = array())
	{
	    $parameters['type'] = 'button';
		return $this->_buttonTag($caption, $parameters);
	}

	protected function _buttonTag($caption, $parameters = array())
	{
	    $parameters['value'] = $caption;
	    $parameters['type'] = empty($parameters['type']) ? 'button' : $parameters['type'];
	    $confirm = !empty($parameters['confirm']) && is_string($parameters['confirm']) ? $parameters['confirm'] : false;
	    if (array_key_exists('confirm', $parameters)) {
	        unset($parameters['confirm']);
	    }
	    if ($confirm) {
            $confirm = str($confirm)->addslashes("'")->toString();
	        $confirm_code = "if (!confirm('{$confirm}')) return false;";
            if (empty($parameters["onclick"])) {
                $parameters["onclick"] = "";
            }
            $parameters["onclick"] = $confirm_code.$parameters["onclick"];
	    }
	    $action = !empty($parameters['action']) && is_string($parameters['action']) ? $parameters['action'] : false;
	    if (array_key_exists('action', $parameters)) {
	        unset($parameters['action']);
	    }
	    if ($parameters['type'] != 'submit') {
    	    if ($action) {
                $action = str($action)->addslashes("'")->toString();
    	        $action_code = "document.location.href='{$action}';";
                if (empty($parameters["onclick"])) {
                    $parameters["onclick"] = "";
                }
                $parameters["onclick"] .= $action_code;
    	    }
	    }
		return $this->Form->output('<input'.$this->Form->_parseAttributes($parameters, array(), ' ', '').'/>');
	}

	function back($url, $parameters=array())
	{
	    $opts = array(
	       'onclick' => "document.location='".$this->Html->url($url)."'; return false;",
        );
        $parameters = am($opts, $parameters);

		return $this->button('submit_back', __d(null, 'back', true), $parameters);
	}

	function toggleButton($id, $parameters = array())
	{
	    $default = array(
	       'enableCaption' => __d(null, 'Hide', true),
	       'disableCaption' => __d(null, 'details', true).'…',
	       'title' => '',
	       'link' => '#',
	    );
	    $parameters = am($default, $parameters);

        $linkHTML = $this->startGroup().$this->cell('<em>'.$this->Html->link($parameters['disableCaption'], $parameters['link'], array('title'=>$parameters['title'])).'</em>').$this->endGroup();

        return $this->Javascript->codeBlock("toggleBlock('{$id}', '{$linkHTML}', '{$parameters['enableCaption']}');");
	}

	function error($field, $text = null, $options = array())
	{
		$this->Form->setFormTag($field);
		$options = am(array('wrap' => true, 'class' => 'error-message', 'escape' => true), $options);

		if ($error = $this->Form->tagIsInvalid()) {
			if (is_array($text) && is_numeric($error) && $error > 0) {
				$error--;
			}
			if (is_array($text) && isset($text[$error])) {
				$text = $text[$error];
			} elseif (is_array($text)) {
				$text = null;
			}

			if ($text != null) {
				$error = $text;
			} elseif (is_numeric($error)) {
				$error = '';
			}
            $error = __d('errors', $error, true);
			if ($options['escape']) {
				$error = h($error);
			}
			if ($options['wrap'] === true) {
				return !empty($error) ? $this->Form->Html->div($options['class'], $error) : '';
			} else {
				return $error;
			}
		} else {
			return null;
		}
	}


}

?>
